package src

import (
	"fmt"
	"sync"
	"time"
)

type Task struct {
	TaskFunc   func()
	SecondRest int
	MinuteRest int
	HourRest   int
	next       *Task
	Extra      string
}

func (t Task) Run() {
	t.TaskFunc()
}

type Scheduler struct {
	SecondTime *TimeCycle
	MinuteTime *TimeCycle
	HourTime   *TimeCycle
	wait       *sync.WaitGroup
	wm         *WorkManage
}

func (t Scheduler) RunTaskLinked(task *Task) {
	curTask := task
	for curTask != nil {
		m, s, h := task.MinuteRest, task.SecondRest, task.HourRest
		if m+s+h != 0 {
			t.AddTask(curTask)
		} else {
			t.wm.Push(*curTask)
		}
		curTask = curTask.next
	}
}

func (t *Scheduler) AddTask(task *Task) {
	m := task.MinuteRest
	s := task.SecondRest
	h := task.HourRest
	if m >= 60 || s >= 60 || h >= 60 {
		fmt.Println("Task 时间错误")
		return
	}
	if h > 0 {
		t.HourTime.InsertTask(task, h)
		task.HourRest = 0
	} else if s > 0 {
		t.SecondTime.InsertTask(task, s)
		task.SecondRest = 0
	} else if m > 0 {
		t.MinuteTime.InsertTask(task, m)
		task.MinuteRest = 0
	}
}

func (t *Scheduler) Init() {
	t.SecondTime = new(TimeCycle)
	t.MinuteTime = new(TimeCycle)
	t.HourTime = new(TimeCycle)
	t.wm = new(WorkManage)
	t.wait = new(sync.WaitGroup)
	t.wait.Add(5)
	t.wm.Init(5, t.wait)
	t.wm.Execute()
}

func (t *Scheduler) Loop() {
	t.wait.Wait()
}

func (t Scheduler) RunScheduler() {
	go func() {
		ticker := time.NewTicker(1 * time.Second)
		for {
			select {
			case <-ticker.C:
				t.ProcessTask()
			}
		}
	}()
}

func (t Scheduler) ProcessTask() {
	SecondTask, secondFull := t.SecondTime.GetTask()
	t.RunTaskLinked(SecondTask)
	if secondFull {
		minuteTask, minuteFull := t.MinuteTime.GetTask()
		t.RunTaskLinked(minuteTask)
		if minuteFull {
			hourTask, _ := t.HourTime.GetTask()
			t.RunTaskLinked(hourTask)
		}
	}
}
